package LimitedTimeGame.Day_0224;

/**
 * @author zxc
 * @date 2023/02/24 09:09
 **/

/**
 * 题目 ：统计可以提取的工件
 * 题目详述 ：
 * 存在一个 n x n 大小、下标从 0 开始的网格，网格中埋着一些工件。
 * 给你一个整数 n 和一个下标从 0 开始的二维整数数组 artifacts ，
 * artifacts 描述了矩形工件的位置，其中 artifacts[i] = [r1i, c1i, r2i, c2i] 表示第 i 个工件在子网格中的填埋情况：
 * (r1i, c1i) 是第 i 个工件 左上 单元格的坐标，且
 * (r2i, c2i) 是第 i 个工件 右下 单元格的坐标。
 * 你将会挖掘网格中的一些单元格，并清除其中的填埋物。如果单元格中埋着工件的一部分，那么该工件这一部分将会裸露出来。
 * 如果一个工件的所有部分都都裸露出来，你就可以提取该工件。
 * 给你一个下标从 0 开始的二维整数数组 dig ，其中 dig[i] = [ri, ci] 表示你将会挖掘单元格 (ri, ci) ，返回你可以提取的工件数目。
 * 生成的测试用例满足：
 * 不存在重叠的两个工件。
 * 每个工件最多只覆盖 4 个单元格。
 * dig 中的元素互不相同。
 *
 * 提示：
 * 1 <= n <= 1000
 * 1 <= artifacts.length, dig.length <= min(n2, 105)
 * artifacts[i].length == 4
 * dig[i].length == 2
 * 0 <= r1i, c1i, r2i, c2i, ri, ci <= n - 1
 * r1i <= r2i
 * c1i <= c2i
 * 不存在重叠的两个工件
 * 每个工件 最多 只覆盖 4 个单元格
 * dig 中的元素互不相同
 *
 */
public class DigArtifacts {
    /**
     * 思路 ：
     * ===》
     * （1）首先，将创建二维数组dp && dp中所有元素皆为 0，即代表了n * n的土地未被开发;
     * （2）其次，遍历dig二维数组，去获取需要被开发的土地，即将其在dp数组中对应元素置为1;
     * （3）最后，遍历artifacts数组，遍历每一个工件，看其所占土地是否已经被完全开发;
     * @param n
     * @param artifacts
     * @param dig
     * @return
     */
    public int digArtifacts(int n, int[][] artifacts, int[][] dig) {
        int[][] dp = new int[n][n];
        // 遍历dig数组，将所有开发过的土地 置为1（代表该块土地已经被挖掘）;
        for(int i = 0 ; i < dig.length ; i++){
            dp[dig[i][0]][dig[i][1]] = 1;
        }
        int count = 0;
        for(int i = 0 ; i < artifacts.length ; i++){
            // 工件行之间的距离
            int mLen = artifacts[i][2] - artifacts[i][0];
            // 工件列之间的距离
            int nLen = artifacts[i][3] - artifacts[i][1];
            // 情况一 ：工件是在同一行 && 占用多列;
            if(mLen == 0 && nLen > 0){
                boolean flag = true;
                for(int j = 0 ; j <= nLen ; j++){
                    if(dp[artifacts[i][0]][artifacts[i][1] + j] == 0){
                        flag = false;
                        break;
                    }
                }
                if(flag){
                    count++;
                }
            }
            // 情况二 ：工件在同一列 && 占用多行
            else if(nLen == 0 && mLen > 0){
                boolean flag = true;
                for(int j = 0 ; j <= mLen ; j++){
                    if(dp[artifacts[i][0] + j][artifacts[i][1]] == 0){
                        flag = false;
                        break;
                    }
                }
                if(flag){
                    count++;
                }
            }
            // 情况三 ：工件只占一个位置
            else if (nLen == 0 && mLen == 0){
                if(dp[artifacts[i][0]][artifacts[i][1]] == 1){
                    count++;
                }
            }
            // 情况四 ：工件所占行和列，皆不在同一行和同一列上
            // 由于工件最多覆盖4个位置，所以只可能是田字形;
            else{
                int a = artifacts[i][0];
                int b = artifacts[i][1];
                if(dp[a][b] == 1 && dp[a + 1][b] == 1 && dp[a][b + 1] == 1 && dp[a + 1][b + 1] == 1){
                    count++;
                }
            }
        }
        return count;
    }
}
